package com.xbongbong.paas.call.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.call.CallCenterService;
import com.xbongbong.paas.call.util.CallCenterUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.manager.feign.AliyuncallCenterFeignClient;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.pojo.DetaPhonePojo;
import com.xbongbong.paas.pojo.dto.IsActiveAliyunCallDTO;
import com.xbongbong.paas.pojo.vo.CallCenterModuleVO;
import com.xbongbong.paas.pojo.vo.CallCenterOrgGetByCorpIdVO;
import com.xbongbong.paas.pojo.vo.IsActiveAliyunCallVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.enums.CallCenterTypeEnum;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.CallCenterErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.SystemAppMenuEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.callcenter.CallCenterConstant;
import com.xbongbong.saas.domain.entity.CallCenterAccountEntity;
import com.xbongbong.saas.enums.PhoneExtEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.model.CallCenterAccountModel;
import com.xbongbong.saas.model.CallCenterOrganizationModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2021/12/20 17:15
 */
@Service("callCenterServiceImpl")
public class CallCenterServiceImpl implements CallCenterService {

    private static final Logger LOGGER = LoggerFactory.getLogger(CallCenterServiceImpl.class);

    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private CallCenterOrganizationModel callCenterOrganizationModel;
    @Resource
    private CallCenterAccountModel callCenterAccountModel;
    @Resource
    private AliyuncallCenterFeignClient aliyuncallCenterFeignClient;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private CustomerModel customerModel;


    @Override
    public IsActiveAliyunCallVO isActiveAliyunCall(String corpid, String userId) throws XbbException {
        IsActiveAliyunCallVO vo = new IsActiveAliyunCallVO();
        vo.setActiveAliyunCall(false);
        XbbResponse<IsActiveAliyunCallVO> response = new XbbResponse<>(vo);
        try {
            IsActiveAliyunCallDTO isActiveAliyunCallDTO = new IsActiveAliyunCallDTO();
            isActiveAliyunCallDTO.setCorpid(corpid);
            isActiveAliyunCallDTO.setUserId(userId);
            isActiveAliyunCallDTO.setPlatform(PlatFormEnum.WEB.getValue());
            String lang = LocaleContextHolder.getLocale().toString();
            response = aliyuncallCenterFeignClient.isActiveAliyunCall(isActiveAliyunCallDTO, lang);
            if (!Objects.equals(response.getCode(), ErrorCodeEnum.API_SUCCESS.getCode())) {
//            throw new XbbException(response.getCode(), response.getMsg());
                return new IsActiveAliyunCallVO();
            }
        }catch (Exception e){
        }
        return response.getResult();
    }

    @Override
    public boolean isOpenCallAndAgent(String corpid, String userId) throws XbbException {
        CallCenterModuleVO module = module(corpid, userId);
        Integer moduleType = module.getModuleType();
        boolean isActiveCall = CallCenterUtil.notCallCenterModule(moduleType);
        boolean isOpenCallAndAgent = false;
        if(!isActiveCall){
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("corpid", corpid);
            params.put("moduleType", moduleType);
            params.put("userId", userId);
            params.put("negDel", 1);
            List<CallCenterAccountEntity> callCenterAgent = callCenterAccountModel.findEntitys(params);
            if(callCenterAgent.size() > 0){
                // 坐席用户开放模块(涉及到电话功能，只对坐席开放)
                CallCenterAccountEntity accountEntity = callCenterAgent.get(BasicConstant.ZERO);
                if(Objects.equals(accountEntity.getIsAgent(), 1)){
                    isOpenCallAndAgent = true;
                }
            }
        }
        return isOpenCallAndAgent;
    }

    @Override
    public CallCenterModuleVO module(String corpid, String userId) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("aliasIn", Arrays.asList(SystemAppMenuEnum.CALL_CENTER.getAlias()));
        List<PaasAppEntity> appList = paasAppModel.findEntitys(param);

        List<Integer> getModuleTypeList = new ArrayList<>();
        Integer moduleType = null;
        for (PaasAppEntity paasAppEntity : appList) {
            if (Objects.equals(paasAppEntity.getAlias(), StringConstant.PLATFORM_DUYAN) ||
                    Objects.equals(paasAppEntity.getAlias(), StringConstant.PLATFORM_XBB)) {
                getModuleTypeList.add(XbbRefTypeEnum.getByAlias(paasAppEntity.getAlias()).getCode());
            }
        }
        if (getModuleTypeList.size() == 1) {
            moduleType = getModuleTypeList.get(0);
        } else if (getModuleTypeList.size() > 1) {
            // 针对内测公司同时开启两个呼叫中心特殊处理
            String activeModuleType = paasRedisHelper.getValue(CallCenterConstant.REDIS_KEY_ACTIVE_MODULE_TYPE, corpid + "_" + userId);
            if (StringUtil.isNotEmpty(activeModuleType) && StringUtil.isNumeric(activeModuleType)) {
                moduleType = Integer.parseInt(activeModuleType);
            } else {
                // 默认第一个呼叫中心
                moduleType = getModuleTypeList.get(0);
                if (moduleType != null) {
                    paasRedisHelper.setValue(CallCenterConstant.REDIS_KEY_ACTIVE_MODULE_TYPE, corpid + "_" + userId, moduleType, null);
                }
            }
        }
        CallCenterModuleVO callCenterModuleVO = new CallCenterModuleVO();
        // 度言不考虑提示问题(欠费之后，电话无法呼出)，销帮帮通过标识来提示用户到期状态：
        if(Objects.equals(CallCenterTypeEnum.CALL_CENTER_XBB.getCode(), moduleType)){
            CallCenterOrgGetByCorpIdVO getByCorpIdVO = callCenterOrganizationModel.getByCorpId(corpid, moduleType);
            if (getByCorpIdVO == null) {
                throw new XbbException(CallCenterErrorCodeEnum.API_ERROR_301001);
            }
            Integer endTime = getByCorpIdVO.getEndTime() == null ? Integer.valueOf(0) : getByCorpIdVO.getEndTime();
            // 向上取整
            Integer betweenDays = (int)Math.ceil(DateUtil.betweenDays(DateUtil.getInt(), endTime));
            // 差值补偿
            betweenDays = Objects.equals(0, betweenDays) ? Integer.valueOf(1) : betweenDays;
            if(betweenDays > 0 && betweenDays < 4){
                callCenterModuleVO.setBetweenDays(betweenDays);
                callCenterModuleVO.setStatus("nearExpiring");
            } else if(betweenDays > 3){
                callCenterModuleVO.setStatus("normal");
            } else if(betweenDays < 0){
                callCenterModuleVO.setStatus("expiring");
            }
        }
        callCenterModuleVO.setModuleType(moduleType);
        callCenterModuleVO.setGetModuleTypeList(getModuleTypeList);
        return callCenterModuleVO;
    }

    /**
     * 电话获取
     * @param dataList
     * @param businessType
     * @param corpid
     * @return
     * @throws XbbException
     */
    @Override
    public List<DetaPhonePojo> cusCallPhone(JSONObject dataList, Integer businessType, String corpid, Map<String, FieldAttrEntity> explainMap, HandlerExplainDTO handlerExplainDTO) throws XbbException {
        // todo 号码隐藏解释 海滨
        boolean isShow = false;
        boolean attrVisible = false;
        // 呼叫中心号码封装
        List<DetaPhonePojo> dial = new ArrayList<>();
        JSONArray phoneJsonArray = null;
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
        try {
            if (dataList != null) {
                switch (redundantTemplateTypeEnum) {
                    case CUSTOMER:
                        phoneJsonArray = dataList.getJSONArray(CustomerManagementEnum.PHONE.getAttr());
                        attrVisible = commonHelp.attrCanSee(CustomerManagementEnum.PHONE.getAttr(), explainMap, handlerExplainDTO);
                        if(attrVisible){
                            List<? extends FieldAttrEntity> explainSubFormList = explainMap.get(CustomerManagementEnum.PHONE.getAttr()).getSubForm().getItems();
                            Map<String, FieldAttrEntity> explainSubFormMap = new HashMap<>(explainSubFormList.size());
                            explainSubFormList.forEach((item) -> explainSubFormMap.put(item.getAttr(), item));
                            boolean text2CanSee = commonHelp.attrCanSee(StringConstant.PHONE_TEL_ATTR, explainSubFormMap, handlerExplainDTO);
                            if(text2CanSee){
                                isShow = true;
                            }
                        }
                        break;
                    case CONTACT:
                        phoneJsonArray = dataList.getJSONArray(ContactEnum.PHONE.getAttr());
                        attrVisible = commonHelp.attrCanSee(ContactEnum.PHONE.getAttr(), explainMap, handlerExplainDTO);
                        if(attrVisible){
                            List<? extends FieldAttrEntity> explainSubFormList = explainMap.get(ContactEnum.PHONE.getAttr()).getSubForm().getItems();
                            Map<String, FieldAttrEntity> explainSubFormMap = new HashMap<>(explainSubFormList.size());
                            explainSubFormList.forEach((item) -> explainSubFormMap.put(item.getAttr(), item));
                            boolean text2CanSee = commonHelp.attrCanSee(StringConstant.PHONE_TEL_ATTR, explainSubFormMap, handlerExplainDTO);
                            if(text2CanSee){
                                isShow = true;
                            }
                        }
                        break;
                    case COMMUNICATE_PLAN:
                        Long customerId = FastJsonHelper.getLongOrDefaultFromFormData(dataList, CommunicatePlanEnum.LINK_CUSTOMER.getAttr(), 0L);
                        PaasFormDataEntityExt paasFormDataEntityExt = customerModel.getByKey(customerId, corpid);
                        if (Objects.isNull(paasFormDataEntityExt)) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
                        }
                        phoneJsonArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(paasFormDataEntityExt.getData(), CustomerManagementEnum.PHONE.getAttr(), new JSONArray());
                        attrVisible = commonHelp.attrCanSee(CustomerManagementEnum.PHONE.getAttr(), explainMap, handlerExplainDTO);
                        if(attrVisible){
                            List<? extends FieldAttrEntity> explainSubFormList = explainMap.get(CustomerManagementEnum.PHONE.getAttr()).getSubForm().getItems();
                            Map<String, FieldAttrEntity> explainSubFormMap = new HashMap<>(explainSubFormList.size());
                            explainSubFormList.forEach((item) -> explainSubFormMap.put(item.getAttr(), item));
                            boolean text2CanSee = commonHelp.attrCanSee(StringConstant.PHONE_TEL_ATTR, explainSubFormMap, handlerExplainDTO);
                            if(text2CanSee){
                                isShow = true;
                            }
                        }
                        break;
                    case CLUE:
                        phoneJsonArray = dataList.getJSONArray(ClueEnum.PHONE.getAttr());
                        attrVisible = commonHelp.attrCanSee(ClueEnum.PHONE.getAttr(), explainMap, handlerExplainDTO);
                        if(attrVisible){
                            List<? extends FieldAttrEntity> explainSubFormList = explainMap.get(ClueEnum.PHONE.getAttr()).getSubForm().getItems();
                            Map<String, FieldAttrEntity> explainSubFormMap = new HashMap<>(explainSubFormList.size());
                            explainSubFormList.forEach((item) -> explainSubFormMap.put(item.getAttr(), item));
                            boolean text2CanSee = commonHelp.attrCanSee(StringConstant.PHONE_TEL_ATTR, explainSubFormMap, handlerExplainDTO);
                            if(text2CanSee){
                                isShow = true;
                            }
                        }
                        break;
                    default:
                        return dial;
                }
            }
        }catch (Exception e){
            phoneJsonArray = new JSONArray();
        }
        // 当电话子表单完全不可见的时候，不能拨打
        if(!attrVisible){
            return dial;
        }
        phoneJsonArray = Objects.isNull(phoneJsonArray) ? new JSONArray() : phoneJsonArray;
        for (int i = 0; i < phoneJsonArray.size(); i++) {
            String name = phoneJsonArray.getJSONObject(i).getString("text_1");
            String tel = phoneJsonArray.getJSONObject(i).getString("text_2");
            DetaPhonePojo detaPhonePojo = new DetaPhonePojo();
            detaPhonePojo.setName(PhoneExtEnum.getByCode(name).getName());
            detaPhonePojo.setPhoneNum(tel);
            if (!isShow && tel != null) {
                String telNum;
                if (tel.length() > 5) {
                    telNum = tel.substring(0, 3) + "****" + tel.substring(tel.length() - 2, tel.length());
                } else {
                    telNum = "*****";
                }
                detaPhonePojo.setTelNum(telNum);
            } else {
                detaPhonePojo.setTelNum(tel);
            }
            dial.add(detaPhonePojo);
        }

        return dial;
    }

    @Override
    public boolean isOpenCallDingTalk(String corpid, String userId) throws XbbException {
        CallCenterModuleVO module = module(corpid, userId);
        Integer moduleType = module.getModuleType();
        boolean isActiveCall = Objects.equals(moduleType, CallCenterTypeEnum.CALL_CENTER_DU_YAN.getCode());
        boolean isOpenCallAndAgent = false;
        if(isActiveCall){
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("corpid", corpid);
            params.put("moduleType", moduleType);
            params.put("userId", userId);
            params.put("negDel", 1);
            List<CallCenterAccountEntity> callCenterAgent = callCenterAccountModel.findEntitys(params);
            if(callCenterAgent.size() > 0){
                // 坐席用户开放模块(涉及到电话功能，只对坐席开放)
                CallCenterAccountEntity accountEntity = callCenterAgent.get(BasicConstant.ZERO);
                if(Objects.equals(accountEntity.getIsAgent(), 1)){
                    isOpenCallAndAgent = true;
                }
            }
        }
        return isOpenCallAndAgent;
    }
}
